/**
 * Created by Richard Radlherr.
 * Date: 04.06.2006 19:54
 */

using System;

namespace TagTool.Core
{
	public delegate Object ParseCallback(String description);

	public class InputSlot : Slot
	{
		Object defaultValue;
		OutputSlot input;
		ParseCallback parse = null;
		
		bool active = false;
 		
		public InputSlot(BaseNode owner, String name, Object defaultValue) : base(owner, name, defaultValue.GetType())
		{
			this.defaultValue = defaultValue;
		}
		
		public OutputSlot Input
		{
			get { return input; }
		}
		
		public override Object Value
		{
			get 
			{
				if (input != null)
				{
					return input.Value;
				}
				else
				{
					return defaultValue;
				}
			}
			set	{ }
		}
		
		public Object DefaultValue
		{
			get { return defaultValue; }
			set 
			{ 
				if (Allowed(value))
				{
					defaultValue = value;
				}
			}
		}

		public bool Active
		{
			get { return active; }
			set 
			{ 
				if (input != null)
				{
					if (active && value == false)
					{
						input.ValueChanged -= new ValueChangedEventHandler(InputChanged);
					}
					else if (!active && value == true)
					{
						input.ValueChanged += new ValueChangedEventHandler(InputChanged);
					}
				}
				active = value; 
			}
		}

		public bool Connect(OutputSlot input)
		{
			bool a = Allowed(input.Value);
			if (a)
			{
				this.input = input;
				if (active)
				{
					input.ValueChanged += new ValueChangedEventHandler(InputChanged);
				}
			}
			return a;
		}

		public void UnConnect()
		{
			if (input != null)
			{
				input.ValueChanged -= new ValueChangedEventHandler(InputChanged);
				input = null;
			}
		}
		
		public bool Connected
		{
			get { return input != null; }
		}
		
		public override bool Allowed(Object obj)
		{
			return obj.GetType() == ArgumentType || obj.GetType().IsSubclassOf(ArgumentType);
		}
		
		public BaseNode ConnectedNode
		{
			get { 
				if (input != null)
				{
					return input.Owner;
				}
				else
				{
					return null;
				}
			}
		}
		
		public ParseCallback ParseCallback
		{
			set { parse = value; }
		}
		
		public override bool Editable
		{
			get { return parse != null; }
		}
		
		public override void Parse(String description)
		{
			if (parse != null)
			{
				defaultValue = parse(description);
			}
		}

		private void InputChanged(Object sender, ValueChangedEventArgs e)
		{
			Owner.Update(sender);
		}
	}
}
